package br.ufrj.ad.entidade;

import java.util.TreeMap;

import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;

public class Rodada implements Comparable<Rodada> {
	
	private int numeroRodada;
	
	private DescriptiveStatistics temposDeDownload = new DescriptiveStatistics();
	
	private double inicio;
	private double fim;
	
	private int saidas;
	
	private TreeMap<Integer, Double> tempoTamanhoPopulacao;
	private double tempoUltimaChegadaSaida;
	
	public Rodada(int numRodada, double tempoInicio) {
		this.numeroRodada = numRodada;
		this.inicio = tempoInicio;
		this.tempoTamanhoPopulacao = new TreeMap<Integer, Double>();
	}

	public void setFim(double fim) {
		this.fim = fim;
	}

	public double getDuracao() {
		return fim - inicio;
	}
	
	public void addTempoProTamanhoPopulacao(int tamPopulacao, double variacaoTempo) {
		if(this.tempoTamanhoPopulacao.get(tamPopulacao) == null) {
			this.tempoTamanhoPopulacao.put(tamPopulacao, variacaoTempo);
		} else {
			double tempoJaAcumulado = this.tempoTamanhoPopulacao.get(tamPopulacao);
			this.tempoTamanhoPopulacao.put(tamPopulacao, tempoJaAcumulado+variacaoTempo);
		}
	}
	
	public TreeMap<Integer, Double> getTempoTamanhoPopulacao() {
		return tempoTamanhoPopulacao;
	}

	public void addTempoDownload(double tempoQueAconteceu, double variacaoTempoDownload) {
		if(antesDoFim(tempoQueAconteceu)) {
			temposDeDownload.addValue(variacaoTempoDownload);
		}
	}
	
	private boolean antesDoFim(double tempo) {
		if(fim == 0) {
			return true;
		} else if(tempo < fim) {
			return true;
		} else {
			return false;
		}
		//return fim != 0 && tempo < fim;
	}

	public int getNumeroUploads() {
		return temposDeDownload.getValues().length;
	}
	
	public int getNumeroRodada() {
		return numeroRodada;
	}


	public double getMediaTempoDownloads() {
		return temposDeDownload.getMean();
	}
	
	//P(X < x) para o calculo da CDF
	public double getPercentil(double x) {
		return temposDeDownload.getPercentile(x);
	}
	
	public double getMediana() {
		//A mediana só está no toString, não consigo pegar pelo get
		String[] s = temposDeDownload.toString().split("\\n");
		String medianaStr = s[6].substring(s[6].indexOf(":")+2);
		return Double.parseDouble(medianaStr);
	}
	
	public DescriptiveStatistics getStatistica() {
		return temposDeDownload;
	}
	public double getTempoUltimaChegadaSaida() {
		if(tempoUltimaChegadaSaida == 0) {
			return inicio;
		}else {
			return tempoUltimaChegadaSaida;
		}
	}

	public void setTempoUltimaChegadaSaida(double tempoUltimaChegadaSaida) {
		this.tempoUltimaChegadaSaida = tempoUltimaChegadaSaida;
	}

	@Override
	public int compareTo(Rodada o) {
		return new Integer(this.numeroRodada).compareTo(o.numeroRodada);
	}

	public void addSaida() {
		this.saidas++;
	}

	public int getSaidas() {
		return saidas;
	}
	
}
